package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

func eval(a, b int, opType string) (int, error) {
	switch opType {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		q, _ := div(a, b)
		return q, nil
	default:
		return 0, fmt.Errorf("unsupported operation: %s", opType)
	}
}

func div(a, b int) (q, r int) {
	return a / b, a % b
}

func swap(a, b int) (int, int) {
	return b, a
}

func sum(numbers ...int) int {
	sum := 0
	for _, data := range numbers {
		sum += data
	}
	return sum
}

func apply(op func(int, int) int, a, b int) int {
	// 反射拿到函数名字
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("calling function is: %s with args %d, %d \n", opName, a, b)
	return op(a, b)
}

func main() {

	fmt.Println("error handling")
	if result, err := eval(4, 3, "x"); err != nil {
		fmt.Println("Error: ", err)
	} else {
		fmt.Println("Result: ", result)
	}

	q, r := div(13, 3)
	fmt.Printf("13 div 3 is %d, mod is %d \n", q, r)

	a, b := 1, 2
	a, b = swap(a, b)
	fmt.Println("a, b after swap is : ", a, b)

	fmt.Println("1+2+3=", sum(1, 2, 3))

	fmt.Println("pow(3, 4) is :", apply(
		// 匿名函数
		func(a, b int) int {
			return int(math.Pow(float64(a), float64(b)))
		}, 3, 4))
}
